﻿using Framework.Common.EnumOperation;
using Framework.Common.ExceptionOperation;
using Framework.Redis;
using PaPaPa.Data.EF;
using PaPaPa.Models.BasicData;
using PaPaPa.Models.Accounts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PaPaPa.Core.Users
{
    public class UserCore
    {
        #region Redis

        private static User GetUserCacheByUserName(string userName)
        {
            return RedisSingleton.GetInstance.Client.HGet<User>("User", "UserName:" + userName);
        }

        private static User GetUserCacheById(int id)
        {
            return RedisSingleton.GetInstance.Client.HGet<User>("User", "Id:" + id);
        }

        #endregion

        public async static Task<User> FindUserById(int id)
        {
            User user = GetUserCacheById(id);

            if (user != null)
            {
                return user;
            }

            using (var ef = new DataWrapper<User>())
            {
                user = await ef.FindAsync(x => x.Id == id);
                if (user == null)
                {
                    throw new GException(EnumHelper.GetEnumDescription(ErrorCode.UserIdIsNotExists).Description);
                }
                return user;
            }
        }

        public async static Task<User> FindUserByUserName(string userName, bool returnNull = false)
        {
            User user = GetUserCacheByUserName(userName);

            if (user != null)
            {
                return user;
            }

            using (var ef = new DataWrapper<User>())
            {
                user = await ef.FindAsync(x => x.UserName == userName);
                if (user == null && !returnNull)
                {
                    throw new GException(EnumHelper.GetEnumDescription(ErrorCode.CanNotFoundUserName).Description);
                }
                return user;
            }
        }

        public async static Task CreateUser(User user)
        {
            User existsUser = await FindUserByUserName(user.UserName, true);
            if (existsUser != null)
            {
                throw new GException(EnumHelper.GetEnumDescription(ErrorCode.UserNameExists).Description);
            }

            using (var ef = new DataWrapper<User>())
            {
                ef.Add(user);
                await ef.SaveAsync();
            }
        }

        public async static Task ModifyPasswordAsync(int id, string oldPassword, string newPassword)
        {
            var user = await FindUserById(id);
            if (user.Password != oldPassword)
            {
                throw new GException(EnumHelper.GetEnumDescription(ErrorCode.PasswordError).Description);
            }

            user.Password = newPassword;

            using (var ef = new DataWrapper<User>())
            {
                ef.Add(user);
                await ef.SaveAsync();
            }
        }

        public async static Task ModifyUserBasicData(User user)
        {
            using (var ef = new DataWrapper<User>())
            {
                ef.Modify(user);
                await ef.SaveAsync();
            }
        }
    }
}
